package com.example.testdemo.kinetic.sprite.tank.player;

import java.util.ArrayList;
import java.util.List;

import org.andengine.engine.handler.physics.PhysicsHandler;
import org.andengine.entity.IEntity;
import org.andengine.opengl.texture.region.ITiledTextureRegion;

import com.example.testdemo.TankGameActivity;
import com.example.testdemo.ai.TrafficLaw.TileVertex;
import com.example.testdemo.controllers.FcController;
import com.example.testdemo.kinetic.data.DataOfPlayerTank;
import com.example.testdemo.kinetic.interfaces.IEnergyStorable;
import com.example.testdemo.kinetic.sprite.TankSprite;
import com.example.testdemo.kstatic.sprite.ItemSprite;

public abstract class PlayerBaseTank extends TankSprite {
	
	public final static String BASE_NAME = PlayerBaseTank.class.getSimpleName();

	public interface IOnPositionChangedListener {
		public void onPositionChanged(float curX, float curY);
	}

	private FcController mController = null;

	public DataOfPlayerTank mData;

	private boolean mInvincible = false;

	protected boolean mGhost = false;

	protected List<IOnPositionChangedListener> mPosChangedListenerList = new ArrayList<PlayerBaseTank.IOnPositionChangedListener>();

	// IEnergyStorable
	private final float EXPANSION_FACTOR = 0.1f;
	private int mEnergyLevel = 0;

	public PlayerBaseTank(int whichScene, String pName, float pX, float pY,
	        ITiledTextureRegion pTiledTextureRegion, TankGameActivity pActivity) {
		super(whichScene, pName, pX, pY, pTiledTextureRegion, pActivity);
		mData = new DataOfPlayerTank(DataOfPlayerTank.LIVES_NORMAL,
		        DataOfPlayerTank.STRENGTH_1, DataOfPlayerTank.DEFENCE_1,
		        DataOfPlayerTank.MOVE_SPEED_1);
		setPhysicsHandler();
	}

	public void registerListenPostionChanged(IOnPositionChangedListener listener) {
		if (!mPosChangedListenerList.contains(listener)) {
			mPosChangedListenerList.add(listener);
		}
	}

	private final float DIFF_TEXTURE_TRAFIC_TILED = 0;

	public void setPhysicsHandler() {
		PhysicsHandler handler = new PhysicsHandler(this) {
			@Override
			protected void onUpdate(float pSecondsElapsed, IEntity pEntity) {
				TileVertex pre = new TileVertex(pEntity.getX(), pEntity.getY());
				super.onUpdate(pSecondsElapsed, pEntity);
				TileVertex cur = new TileVertex(pEntity.getX(), pEntity.getY());

				mOnScene.getSceneResources().mTrafficLaw.restrict(mGhost,
				        PlayerBaseTank.this, DIFF_TEXTURE_TRAFIC_TILED, pre,
				        cur);

				for (IOnPositionChangedListener l : mPosChangedListenerList) {
					l.onPositionChanged(getX(), getY());
				}
			}
		};
		setPhysicsHandler(handler);
	}

	public void setController(FcController controller) {
		mController = controller;
	}

	@Override
	public void resetSpriteData() {
		if (mData != null) {
			mData.reset();
		}
	}

	public boolean isInvincible() {
		return mInvincible;
	}

	public void setInvincible(boolean inVincible) {
		mInvincible = inVincible;
	}

	protected void pickItem(ItemSprite item) {
		item.setVisible(false);
		switch (item.getItemType()) {
		case ItemSprite.TYPE_DEFENCE:
			mData.setDefence(mData.getDefence() + 1);
			break;
		case ItemSprite.TYPE_SPEED:
			mData.setMoveSpeed(mData.getMoveSpeed() + 10);
			break;
		case ItemSprite.TYPE_LIFE:
			if (mController != null) {
				mController.addPlayerLife();
			}
			break;
		case ItemSprite.TYPE_GHOST:
			mGhost = true;
			break;
		}
	}

	@Override
	public void destroyed() {
		super.destroyed();
		mGhost = false;
		clearEnergy();
	}

	// IEnergyStorable

	@Override
	public void setEnergyLevel(int level) {
		if (level >= IEnergyStorable.MIN_LEVEL
		        && level <= IEnergyStorable.MAX_LEVEL) {
			mEnergyLevel = level;
			setScale(1 + (mEnergyLevel * EXPANSION_FACTOR));
		}
	}

	@Override
	public void levelUpEnergy() {
		if (mEnergyLevel >= IEnergyStorable.MIN_LEVEL
		        && mEnergyLevel < IEnergyStorable.MAX_LEVEL) {
			mEnergyLevel++;
			setScale(1 + (mEnergyLevel * EXPANSION_FACTOR));
		}
	}

	@Override
	public void clearEnergy() {
		setEnergyLevel(IEnergyStorable.LEVEL_0);
	}

	@Override
	public int getEnergyLevel() {
		return mEnergyLevel;
	}

}
